package com.etone.smartAudit.utils.word;

import com.etone.smartAudit.enums.DataBaseType;
import com.etone.smartAudit.utils.DateUtil;
import com.etone.smartAudit.utils.ZipUtil;
import com.etone.smartAudit.utils.database.DatabaseUtil;
import com.etone.smartAudit.vo.auditException.AuditExceptionByteArrayOutputStream;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author: sovy
 * @date: 2021/1/18
 * @description:
 */
@Component
public class WordTemplateUtil {

    private static String templateFilePath;

    private static String database;

    private static String gpSchema;

    private static String gpDatabase;

    private static String gpIp;

    private static Integer gpPort;

    private static String gpUsername;

    private static String gpPassword;

    /**
     * 模板缺省值
     */
    private static String defaultResourceTemplateFilePath = "word/areaReportTemplate.docx";

    @Value("${audit.word.:}")
    public void setDefaultFilePath(String templatePath) {
        WordTemplateUtil.templateFilePath = templatePath;
    }

    @Value("${spring.datasource.database}")
    public void setDatabase(String database) {
        WordTemplateUtil.database = database;
    }

    @Value("${spring.gpds.schema}")
    public void setGpSchema(String gpSchema) {
        WordTemplateUtil.gpSchema = gpSchema;
    }

    @Value("${spring.gpds.database}")
    public void setGpDatabase(String gpDatabase) {
        WordTemplateUtil.gpDatabase = gpDatabase;
    }

    @Value("${spring.gpds.ip}")
    public void setGpIp(String gpIp) {
        WordTemplateUtil.gpIp = gpIp;
    }

    @Value("${spring.gpds.port}")
    public void setGpPort(Integer gpPort) {
        WordTemplateUtil.gpPort = gpPort;
    }

    @Value("${spring.gpds.username}")
    public void setGpUsername(String gpUsername) {
        WordTemplateUtil.gpUsername = gpUsername;
    }

    @Value("${spring.gpds.password}")
    public void setGpPassword(String gpPassword) {
        WordTemplateUtil.gpPassword = gpPassword;
    }

    /**
     * 获取模板文件流
     *
     * @return
     * @throws IOException
     */
    public static InputStream readStream() throws IOException {
        if (StringUtils.isEmpty(templateFilePath)) {
            ClassPathResource classPathResource = new ClassPathResource(defaultResourceTemplateFilePath);
            return classPathResource.getInputStream();
        }
        return new FileInputStream(templateFilePath);
    }

    /**
     * 获取输出流
     *
     * @param params
     * @param outputStream
     * @return
     */
    public static OutputStream writeStream(Map<String, Object> params, OutputStream outputStream) {
        XWPFDocument xwpfDocument = null;
        Connection connection = null;
        try {
            xwpfDocument = new XWPFDocument();
            connection = DatabaseUtil.getConnection(gpIp, DataBaseType.GREENPLUM, gpUsername, gpPassword, gpPort, gpDatabase);
            AuditExceptionCityReportWordUtil auditExceptionCityReportWordUtil = new AuditExceptionCityReportWordUtil(xwpfDocument, params, connection);
            auditExceptionCityReportWordUtil.run();
            xwpfDocument.write(outputStream);
            return outputStream;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (xwpfDocument != null) {
                try {
                    xwpfDocument.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }
        return null;
    }

    /**
     * 批量写流
     *
     * @param params
     * @param xwpfDocument
     * @param outputStream
     * @return
     */
    public static OutputStream writeStream(Map<String, Object> params, XWPFDocument xwpfDocument, OutputStream outputStream) {
        List<XWPFParagraph> paragraphs = xwpfDocument.getParagraphs();
        for (XWPFParagraph paragraph : paragraphs) {
            List<XWPFRun> runs = paragraph.getRuns();
            for (XWPFRun run : runs) {
                System.out.println(run.text());
                for (String param : params.keySet()) {
                    if (run.text().contains("${" + param + "}")) {
                        run.setText(run.text().replaceAll("\\$\\{" + param + "\\}", String.valueOf(params.get(param))), 0);
                    }
                }
            }
        }
        try {
            xwpfDocument.write(outputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 批量写入流
     *
     * @param datas
     * @return
     */
    public static List<AuditExceptionByteArrayOutputStream> batchWriteStream(List<Map<String, Object>> datas) {
        XWPFDocument xwpfDocument = null;
        ByteArrayOutputStream destOutStream = null;

        List<AuditExceptionByteArrayOutputStream> outputStreams = new ArrayList<>();
        try {
            Connection connection = null;
            for (Map<String, Object> params : datas) {
                try {
                    InputStream inputStream = readStream();
                    xwpfDocument = new XWPFDocument(inputStream);

                    AuditExceptionByteArrayOutputStream outputStream = new AuditExceptionByteArrayOutputStream();
                    outputStream.setFileName(params.get("reportPeriods") + "地市报告-" + params.get("city") + ".docx");
                    params.put("gpSchema", gpSchema);

                    connection = DatabaseUtil.getConnection(gpIp, DataBaseType.GREENPLUM, gpUsername, gpPassword, gpPort, gpDatabase);
                    AuditExceptionCityReportWordUtil auditExceptionCityReportWordUtil = new AuditExceptionCityReportWordUtil(xwpfDocument, params, connection);
                    auditExceptionCityReportWordUtil.run();
                    xwpfDocument.write(outputStream);
                    outputStreams.add(outputStream);
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (connection != null) {
                        connection.close();
                    }
                    if (xwpfDocument != null) {
                        try {
                            xwpfDocument.close();
                        } catch (IOException ioException) {
                            ioException.printStackTrace();
                        }
                    }
                }

            }
        } catch (Exception ioException) {
            ioException.printStackTrace();
        } finally {
            if (destOutStream != null) {
                try {
                    destOutStream.close();
                } catch (IOException ioException) {
                    ioException.printStackTrace();
                }
            }

        }

        return outputStreams;
    }

    /**
     * 批量导出
     *
     * @param datas
     * @param fileName
     */
    public static MultipartFile batchExport(List<Map<String, Object>> datas, String fileName) {

        List<AuditExceptionByteArrayOutputStream> outputStreams = batchWriteStream(datas);
        return ZipUtil.ioTOMultipartFile(outputStreams, fileName);
    }

    /**
     * 导出docx
     *
     * @param dataMap
     * @param response
     */
    public static void export(Map<String, Object> dataMap, HttpServletResponse response) {
        try {
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
            //让浏览器下载文件,name是上述默认文件下载名
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(dataMap.get("city") + "风险扫描报告" + dataMap.get("date") + ".docx", "UTF-8"));
            response.flushBuffer();
            ServletOutputStream outputStream = response.getOutputStream();
            writeStream(dataMap, outputStream);

        } catch (IOException ioException) {
            ioException.printStackTrace();
        }
    }

}
